# !/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
===========================
@Time : 2022/9/13 0013 21:34
@Author : 测试开发工程师
@File : 8. linux 三剑客之 sed.py
@Software: PyCharm
============================
"""

"""
流式编辑器：定位并修改数据
sed 基本语法与常用参数
    语法结构 sed [add]X[options]
    -e 表达式
    sed -n '2p'打印第二行
    sed 's#hello#world#' 修改
    -i 直接修改源文件
    -E 扩展表达式
    -debug 调式

sed pattern 表达式
    行数与行数范围 ： 20 30，50
    正则匹配 /pattern/
    区间匹配//,//

sed 是一款强大的非交互式文本编辑器，可以对文本文件进行增删改查操作，支持按行，按字段，按正则匹配文本内容
sed 在处理文本时是逐行读取文件内容，读到匹配的就根据指令做操作，不匹配就跳过

打印数据：
    sed -n '1p' /tmp/1   结果是： a,1,10
    sed -n '1,3p' /tmp/1 
    结果是：
        a,1,10
        a,2,20
        a,3,30
        
sed acyion 表达式
    p 打印，通常结合 -n 参数： sed -n '2p'
    s 查找替换： s/替换前/需要替换的数据/[FLAGS]
    d 删除，删除前两行 sed '1,2d'    sed '$d' /tmp/1.txt($代表最后一行)
    a 追加
    c 改变
    i 插入内容到匹配行之前
    e 执行命令
    分组匹配与字段提取：sed 's#([0-9])|([a-z])#\1\2#'

行数操作：
    打印特定行 sed -n 2p
    删除最后一行 sed $d

s 表达式
    s 表示替换    
    s 后面的追加字符可以为任意字符  
    g 表示全局匹配   
    & 代表匹配内容
    
    例如： 
        将机构中的 a 替换成 greate_a  ->   sed  's/a/greate_a' /tmp/1
        以1结尾的数据全部乘以100  ->   sed  's#1$#100#' /tmp/1
        对所有的1换成9  ->   sed  's#1#9#g' /tmp/1
        在a：前加123  echo a:b:c | sed 's/:/123&'   -> 结果是： a123:b:c
        在所有：前加123  echo a:b:c | sed 's/:/123&/g'   -> 结果是： a123:b123:c
        在a：后加123   echo a:b:c | sed 's/:/&123'   -> 结果是： a:123b:c
        echo a:b:c | sed 's#:#|#g'   -> 结果是： a|b|c
        
反向引用：
    使用()对数据进行分组
    使用\1\2 反向引用分组
    例如：
    将1，2，3数字进行颠倒   echo 0 1 2 3 4 | sed -E 's#([1-3]) ([1-3]) ([1-3])#\3 \2 \1#'   ->  结果是： 0 3 2 1 4
    在 d 之前加上123  echo abd | sed '/d/i 123'  ->   123abd
        

一.  向文件中添加或插入值
cat 1.txt
abc
123 123
def
456
sed '3ahello' 1.txt #向第三行后面添加hello，3表示行号
结果是：
abc
123 123
def
hello
456


2.
sed '/123/ahello' 1.txt #向内容123后面添加hello，如果文件中有多行包括123，则每一行后面都会添加
结果是：
abc
123 123
hello
def
hello
456


3.
sed '$ahello' 1.txt #在最后一行添加hello
结果是：
abc
123 123
hello
def
hello
456
hello


二. 更改文件中指定的行
cat 1.txt
abc
123 123
def
456

sed '1chello' 1.txt #将文件1.txt的第一行替换为hello
结果是：
hello
123 123
def
456


三. 删除文件中的行
cat 1.txt
abc
123 123
def
456
sed '3d' 1.txt #删除第三行
结果是：
abc
123 123
456

sed '1~2d' 1.txt #从第一行开始删除，每隔2行就删掉一行，即删除奇数行
sed '1,2d' 1.txt #删除1~2行
sed '1,2!d' 1.txt #删除1~2之外的所有行
sed '$d' 1.txt #删除最后一行
sed '/123/d' 1.txt #删除匹配123的行
sed '/123/,$d' 1.txt #删除从匹配123的行到最后一行


四. 替换文件中的内容
cat 1.txt
abc
123 123
def
456
123
sed 's/123/hello/' 1.txt #将文件中的123替换为hello，默认只替换每行第一个123
结果是：
abc
hello 123
def
456
hello

sed 's/123/hello/g' 1.txt #将文本中所有的123都替换为hello
sed 's/123/hello/2' 1.txt #将每行中第二个匹配的123替换为hello


五. 打印文件中的行
cat 2.txt
468546sadas
acascfadc
cdscd
5scasc

sed -n '3p' 1.txt #打印文件中的第三行内容
sed -n '2~2p' 1.txt #从第二行开始，每隔两行打印一行，波浪号后面的2表示步长
sed -n '$p' 1.txt #打印文件的最后一行
sed -n '1,3p' 1.txt #打印1到3行


六. 打印文件的行号
sed -n "$=" 1.txt #打印1.txt文件最后一行的行号（即文件有多少行，和wc -l 功能类似）
sed -n '/error/=' 1.txt #打印匹配error的行的行号
sed -n '/error/{=;p}' 1.txt #打印匹配error的行的行号和内容（可用于查看日志中有error的行及其内容）


七. 从文件读取内容
sed 'r 2.txt' 1.txt #将文件2.txt中的内容，读入1.txt中，会在1.txt中的每一行后都读入2.txt的内容
sed '3r 2.txt' 1.txt #在1.txt的第3行之后插入文件2.txt的内容（可用于向文件中插入内容）
sed '/245/r 2.txt' 1.txt #在匹配245的行之后插入文件2.txt的内容，如果1.txt中有多行匹配456则在每一行之后都会插入


八. 向文件中写入内容

"""